/*
Copyright SecureKey Technologies Inc. All Rights Reserved.

SPDX-License-Identifier: Apache-2.0
*/
package chpvdr

import (
	"crypto/sha256"
	"strconv"

	"git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/common/options"
	"git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/providers/ichain"
)

// ctxtCacheKey chain provider 上下文的缓存key
type ctxtCacheKey struct {
	key     string
	context ichain.ClientContext
}

func newCtxtCacheKey(ctx ichain.ClientContext) (*ctxtCacheKey, error) {
	identity, err := ctx.Serialize()
	if err != nil {
		return nil, err
	}

	h := sha256.New()
	if _, err := h.Write(identity); err != nil {
		return nil, err
	}

	hash := h.Sum(nil)

	return &ctxtCacheKey{
		key:     string(hash),
		context: ctx,
	}, nil
}

func (k *ctxtCacheKey) String() string {
	return k.key
}

type cacheKey struct {
	chainConfig ichain.ChainCfg
}

func newCacheKey(chConfig ichain.ChainCfg) *cacheKey {
	return &cacheKey{
		chainConfig: chConfig,
	}
}

func (k *cacheKey) String() string {
	return k.chainConfig.ID()
}

type eventCacheKey struct {
	key         string
	chainConfig ichain.ChainCfg
	opts        []options.Opt
}

func newEventCacheKey(chConfig ichain.ChainCfg, opts ...options.Opt) (*eventCacheKey, error) {
	params := defaultParams()
	options.Apply(params, opts)

	h := sha256.New()
	if _, err := h.Write([]byte(params.getOptKey())); err != nil {
		return nil, err
	}
	hash := h.Sum([]byte(chConfig.ID()))

	return &eventCacheKey{
		chainConfig: chConfig,
		key:         string(hash),
		opts:        opts,
	}, nil
}

func (k *eventCacheKey) Opts() []options.Opt {
	return k.opts
}

func (k *eventCacheKey) String() string {
	return k.key
}

type params struct {
	permitBlockEvents bool
}

func defaultParams() *params {
	return &params{}
}

func (p *params) PermitBlockEvents() {
	p.permitBlockEvents = true
}

func (p *params) getOptKey() string {
	optKey := "blockEvents:" + strconv.FormatBool(p.permitBlockEvents)
	return optKey
}
